package com.wxsong.authplatform.authweb.controller.users;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wxsong.authplatform.authweb.util.Base64Util;
import com.wxsong.authplatform.authweb.util.ListResponse;
import com.wxsong.authplatform.authweb.util.Response;
import com.wxsong.authplatform.authweb.util.ResponseCode;
import com.wxsong.authplatform.authweb.controller.BaseController;
import com.wxsong.authplatform.authweb.controller.users.dto.UserDTO;
import com.wxsong.authplatform.authweb.exception.InstantException;
import com.wxsong.authplatform.authweb.model.users.Users;
import com.wxsong.authplatform.authweb.service.users.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/users")
public class UserController extends BaseController {

    private Logger logger = LoggerFactory.getLogger(UserController.class);

    @Resource
    private UserService userService;

    @RequestMapping(value = "/index")
    public String index(){
        return "users/index";
    }
    @RequestMapping(value = "/add_index")
    public String toAdd(){
        return "users/add";
    }
    @RequestMapping(value = "/update_index")
    public String toUpdate(ModelMap modelMap, String ids){
        String id = Base64Util.decode(ids);
        Users users = userService.getById(Long.parseLong(id));
        modelMap.put("users", users);
        modelMap.put("id", Base64Util.encode(users.getId()+""));
        return "users/update";
    }
    @RequestMapping(value = "/auth_index")
    public String toAuth(ModelMap modelMap, String id){
        id = Base64Util.decode(id);
        Long longId = Long.parseLong(id);
        Users users = userService.getById(longId);
//        Long[] ids = ids(users.getRoles());
//        List<Role> hasRole = userService.hasRoles(ids);
//        List<Role> noRole = userService.noRoles(ids);
//        modelMap.put("has", hasRole);
//        modelMap.put("no", noRole);
        modelMap.put("id", Base64Util.encode(users.getId()+""));
        return "users/auth";
    }

    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ResponseBody
    public Response list(UserDTO userDTO){
        System.out.println(userDTO);
        Map<String, Object> paramMap = Maps.newHashMap();
        List list = Lists.newArrayList();
        try {
            paramMap.put("name", userDTO.getName());
            Long count = userService.count(paramMap);
            if (count.compareTo(0l) > 0) {
                list = userService.list(getFrom(userDTO.getPage(), getSize(userDTO.getRows())), getSize(userDTO.getRows()), paramMap);
            }
            parseList(list);
            return ListResponse.success(count, list);
        }catch (Exception e){
            logger.error("/user/list  error", e);
            return Response.fail(ResponseCode.FAIL.info);
        }

    }

    private void parseList(List<Users> list) {
        List tmp = Lists.newArrayList();
        for (Users user : list){
            UserDTO userDTO = new UserDTO();
            userDTO.setId(Base64Util.encode(user.getId()+""));
            userDTO.setName(user.getName());
            userDTO.setAge(user.getAge());
            userDTO.setBirth(new Timestamp(user.getBirth().getTime()));
            userDTO.setCreateTime(new Timestamp(user.getCreateTime().getTime()));
            tmp.add(userDTO);
        }
        list.clear();
        list.addAll(tmp);
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public Response add(UserDTO userDTO){
        Map resultMap = Maps.newHashMap();
        Users users = changeUser(userDTO);
        try {
            check(users);
            int i = userService.add(users);
            if(i < 1){
                return Response.fail(ResponseCode.ADD_USER_FAIL);
            }
        }catch (InstantException e){
            logger.error("/user/add  error", e);
            return Response.fail(ResponseCode.ADD_USER_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/user/add  error", e);
            return Response.fail(ResponseCode.ADD_USER_FAIL);
        }
        return Response.success(resultMap);
    }

    @RequestMapping(value = "/modify", method = RequestMethod.POST)
    @ResponseBody
    public Response modify(UserDTO userDTO){
        Map resultMap = Maps.newHashMap();
        try {
            Long id = Long.parseLong(Base64Util.decode(userDTO.getId()));
            Users users = userService.getById(id);
            if(null == users){
                throw new InstantException("用户不存在");
            }
            int c = userService.updateInfo(id, userDTO.getName(), userDTO.getAge(), userDTO.getBirth());
            if (c < 0) {
                return Response.fail(ResponseCode.UPDATE_USER_FAIL);
            }
        }catch (InstantException e){
            logger.error("/user/modify  error", e);
            return Response.fail(ResponseCode.ADD_USER_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/user/modify  error", e);
            return Response.fail(ResponseCode.UPDATE_USER_FAIL);
        }
        return Response.success(resultMap);
    }
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public Response delete(String idStr){
        Map resultMap = Maps.newHashMap();
        try {
            Long[] ids = decodeIds(idStr);
            int count = userService.delete(ids);
            if (count < 0) {
                return Response.fail(ResponseCode.DELETE_USER_FAIL);
            }
        }catch (InstantException e){
            logger.error("/user/delete  error", e);
            return Response.fail(ResponseCode.ADD_USER_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/user/delete  error", e);
            return Response.fail(ResponseCode.DELETE_USER_FAIL.info);
        }
        return Response.success(resultMap);
    }
    @RequestMapping(value = "/modifyAuth", method = RequestMethod.POST)
    @ResponseBody
    public Response modifyAuth(String ids, String userId){
        Map resultMap = Maps.newHashMap();
        try {
            Subject subject = SecurityUtils.getSubject();
//            Users users = (Users)subject.getSession().getAttribute(Const.SESSION_USER_KEY);//操作人
            Users user = userService.getById(Long.parseLong(Base64Util.decode(userId)));
            if(null == user){
                throw new InstantException("被授权用户为空");
            }
//            ids = decodeIdsToString(ids);
            int count = userService.modifyAuth(ids, user.getId());
            if (count < 0) {
                return Response.fail(ResponseCode.DELETE_USER_FAIL);
            }
        }catch (InstantException e){
            logger.error("/user/delete  error", e);
            return Response.fail(ResponseCode.ADD_USER_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/user/delete  error", e);
            return Response.fail(ResponseCode.DELETE_USER_FAIL.info);
        }
        return Response.success(resultMap);
    }

    private boolean check(Users users) throws InstantException{
        if(StringUtils.isBlank(users.getName()) || StringUtils.isBlank(users.getPassword()) || users.getAge() < 1){
            throw new InstantException("参数不合法");
        }
        return true;
    }

    private Users changeUser(UserDTO userDTO) {
        String name = userDTO.getName();
        String password = userDTO.getPassword();
        int age = userDTO.getAge();
        Timestamp birth = userDTO.getBirth();
        Users user = new Users(name, age, birth, password);
        return user;
    }
}
